import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class MysticFighter extends Script {

	boolean Piety = false;
	boolean Chivalry = false;
	boolean MysticMight = false;
	boolean EagleEye = false;
	boolean UltimateStrength = false;
	boolean IncredibleReflexes = false;

	public boolean Guthan = false;
	public boolean useGuthan = false;
	public int[] GuthanSpears = new int[] { 4910, 4911, 4912, 4913 };
	public int GuthanHelm = 4916;
	public int GuthanBody = 4922;
	public int GuthanLegs = 4904;

	public boolean spec = false;

	private RSNPC currentNPC = null;
	private RSTile currentWalkTile = null;

	public boolean safeSpot = false;
	RSTile safeSpotTile;

	int CurSTAT;
	int RealSTAT;
	int stat;
	public boolean potion = false;
	int[] potID;

	int[] origArmour;
	int myArrows;

	public static int[] FoodID = { 1895, 1893, 1891, 4293, 2142, 291, 2140,
			3228, 9980, 7223, 6297, 6293, 6295, 6299, 7521, 9988, 7228, 2878,
			7568, 2343, 1861, 13433, 315, 325, 319, 3144, 347, 355, 333, 339,
			351, 329, 3381, 361, 379, 380, 10136, 5003, 379, 365, 373, 374,
			7946, 385, 397, 391, 3369, 3371, 3373, 2309, 2325, 2333, 2327,
			2331, 2323, 2335, 7178, 7180, 7188, 7190, 7198, 7200, 7208, 7210,
			7218, 7220, 2003, 2011, 2289, 2291, 2293, 2295, 2297, 2299, 2301,
			2303, 1891, 1893, 1895, 1897, 1898, 1899, 1900, 1901, 1902, 7072,
			7062, 7078, 7064, 7084, 7082, 7066, 7068, 1942, 6701, 6703, 7054,
			6705, 7056, 7060, 2130, 1985, 1993, 1989, 1978, 5763, 5765, 1913,
			5747, 1905, 5739, 1909, 5743, 1907, 1911, 5745, 2955, 5749, 5751,
			5753, 5755, 5757, 5759, 5761, 2084, 2034, 2048, 2036, 2217, 2213,
			2205, 2209, 2054, 2040, 2080, 2277, 2225, 2255, 2221, 2253, 2219,
			2281, 2227, 2223, 2191, 2233, 2092, 2032, 2074, 2030, 2281, 2235,
			2064, 2028, 2187, 2185, 2229, 6883, 1971, 4608, 1883, 1885, 403 };

	public boolean onStart(Map<String, String> args) {
		origArmour = getEquipmentArray();
		myArrows = getEquipmentArray()[13];

		if (safeSpot) {
			safeSpotTile = getMyPlayer().getLocation();
		}
		if (Guthan) {
			useGuthan = true;
		}

		return true;
	}

	/*****************************************************************************
	 * \ CONSTANTS \
	 *****************************************************************************/
	private enum Action {

		ANTIBAN, ATTACK, KILLSCRIPT, PICKUP, PICKUPBONE, USE_INVENTORY, USE_MAGIC, USE_SPECIAL, WAIT, WALK
	}

	// Gets Special
	public int getSpec() {
		return getSetting(300);
	}

	// Gets if Special is Enabled
	public boolean specEnabled() {
		return (getSetting(301)) == 1;
	}

	private boolean equipmentContainsAny(int... items) {
		for (int item : getEquipmentArray())
			for (int id : items)
				if (item == id)
					return true;
		return false;
	}

	public void useDDS() {
		int DDS = 5698;
		if (equipmentContainsAny(DDS)) {
			if (getCurrentTab() != TAB_ATTACK) {
				openTab(TAB_ATTACK);
			}
			try {
				if (getSpec() >= 1000 && !specEnabled() && spec == true) {
					openTab(Constants.TAB_ATTACK);
					clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
					wait(400);
					clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
					wait(400);
					clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
					wait(400);
					clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
					wait(400);
				}
			} catch (Exception e) {
			}
		}
		return;
	}

	public void activatePrayer() {
		if (getCurrentTab() != TAB_PRAYER) {
			openTab(TAB_PRAYER);
		}
		if (Piety) {
			log("Piety Activated!");
			atInterface(RSInterface.getInterface(271).getChild(57));
			wait(random(200, 500));
		}
		if (Chivalry) {
			log("Chivalry Activated!");
			atInterface(RSInterface.getInterface(271).getChild(55));
			wait(random(200, 500));
		}
		if (MysticMight) {
			log("Mystic Might Activated!");
			atInterface(RSInterface.getInterface(271).getChild(45));
			wait(random(200, 500));
		}
		if (EagleEye) {
			log("Eagle Eye Activated!");
			atInterface(RSInterface.getInterface(271).getChild(43));
			wait(random(200, 500));
		}
		if (IncredibleReflexes) {
			log("Incredible Reflexes Activated!");
			atInterface(RSInterface.getInterface(271).getChild(35));
			wait(random(200, 500));
		}
		if (UltimateStrength) {
			log("Ultimate Strength Activated!");
			atInterface(RSInterface.getInterface(271).getChild(33));
			wait(random(200, 500));
		}
	}

	public void equipOrigArmour() throws Exception {
		int[] Equip = getEquipmentArray();
		for (int i = 0; i < origArmour.length; i++) {
			if (origArmour[i] != Equip[i])
				if (inventoryContains(origArmour[i]))
					clickInventoryItem(origArmour[i], "Equip");
		}
	}

	public void eat() {
		for (int i = 0; i < FoodID.length; i++) {
			if (getInventoryCount(FoodID[i]) >= 1) {
				clickInventoryItem(FoodID[i], "Eat");
			}
		}
	}

	public void drinkIt() {
		CurSTAT = skills.getCurrentSkillLevel(stat);
		RealSTAT = skills.getRealSkillLevel(stat);
		if (CurSTAT - RealSTAT <= random(1, 2) && potion == true) {
			for (int i = 0; i < potID.length; i++) {
				if (getInventoryCount(potID[i]) >= 1) {
					clickInventoryItem(potID[i], "Drink");
					return;
				}
			}
		} else {
			wait(random(20, 30));
			return;
		}
	}

	public void pickUp() {
		int ITPIDs = 0;
		final RSTile someCustomItem = getGroundItemByID(ITPIDs);
		if (someCustomItem != null) {
			if (getMyPlayer().getInteracting() == null
					&& !getMyPlayer().isMoving()) {
				clickTile(someCustomItem, "Take " + IDtoName(ITPIDs));
				wait(random(300, 850));
			}
		}
		return;
	}

	public void pickArrows() {
		final RSTile arrows = getGroundItemByID(myArrows);
		if (arrows != null) {
			if (getMyPlayer().getInteracting() == null
					&& !getMyPlayer().isMoving()) {
				clickTile(arrows, "Take " + IDtoName(myArrows));
				wait(random(300, 850));
			}
		}
		return;
	}

	/*****************************************************************************
	 * \ FUNCTIONS \
	 *****************************************************************************/
	private Action getAction() {
		
		

		return null;
	}

	@Override
	public int loop() {
		if (!isLoggedIn()
				|| RSInterface.getInterface(378).getChild(45).getAbsoluteX() > 20
				&& !RSInterface.getInterface(149).isValid()) {
			return random(1200, 3100);
		}

		if (canContinue()) {
			clickContinue();
			return random(544, 1200);
		}

		return random(340, 800);
	}

	// clickTile method by DDM
	public boolean clickTile(RSTile tile, String option) {
		Point p = Calculations.tileToScreen(tile);
		p.x += random(-5, 6);
		p.y += random(-5, 6);
		if (p.x < 0 || p.y < 0) {
			return false;
		}
		moveMouse(p);
		// wait(random(100,150));
		getMenuItems();
		@SuppressWarnings("unused")
		List<String> itemsList = getMenuItems();

		long waitTime = System.currentTimeMillis() + random(50, 250);
		boolean foundOption = false;
		while (System.currentTimeMillis() < waitTime && !foundOption) {
			wait(15);
			foundOption = (itemsList = getMenuItems()).get(0).toLowerCase()
					.contains(option.toLowerCase());
		}
		if (foundOption) {
			clickMouse(true);
			wait(random(150, 300));
			return true;
		}
		clickMouse(false);
		wait(random(150, 300));
		return atMenu(option);
	}

	// Method for clicking an inventoryItem
	public boolean clickInventoryItem(int itemID, String option) {
		if (getCurrentTab() != TAB_INVENTORY) {
			openTab(TAB_INVENTORY);
		}
		int[] items = getInventoryArray();
		java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		int idx = possible.get(random(0, possible.size()));
		Point t = getInventoryItemPoint(idx);
		moveMouse(t, 5, 5);
		long waitTime = System.currentTimeMillis() + random(50, 250);
		boolean found = false;
		while (!found && System.currentTimeMillis() < waitTime) {
			wait(15);
			if ((getMenuItems()).get(0).toLowerCase().contains(
					option.toLowerCase())) {
				found = true;
			}
		}
		if (found) {
			clickMouse(true);
			wait(random(150, 250));
			return true;
		}
		clickMouse(false);
		wait(random(150, 250));
		return atMenu(option);
	}

	// Clicks a NPC by Ruski
	public boolean clickNPC(RSNPC npc, String action) {
		if (npc == null) {
			return false;
		}
		RSTile tile = npc.getLocation();
		if (!tile.isValid()) {
			return false;
		}

		try {
			Point screenLoc = npc.getScreenLocation();
			if (distanceTo(tile) > 6 || !pointOnScreen(screenLoc)) {
				turnToTile(tile);
			}
			for (int i = 0; i < 12; i++) {
				screenLoc = npc.getScreenLocation();
				if (!npc.isValid() || !pointOnScreen(screenLoc)) {
					return false;
				}
				moveMouse(screenLoc, 5, 5);
				if (getMenuItems().get(0).toLowerCase().contains(
						npc.getName().toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
			}
			List<String> menuItems = getMenuItems();
			long waitTime = System.currentTimeMillis() + random(50, 250);
			boolean foundOption = false;

			if (menuItems.isEmpty()) {
				return false;
			}
			while (System.currentTimeMillis() < waitTime && !foundOption) {
				wait(15);
				foundOption = (menuItems = getMenuItems()).get(0).toLowerCase()
						.contains(action.toLowerCase());
			}
			if (foundOption) {
				clickMouse(true);
				wait(random(150, 300));
				return true;
			}
			clickMouse(false);
			wait(random(150, 300));
			return atMenu(action);
		} catch (Exception e) {
			System.out.print("clickNPC(RSNPC, String) error: " + e);
			return false;
		}
	}

	public String IDtoName(int id) {
		try {
			URL url = new URL("http://itemdb-rs.runescape.com/viewitem.ws?obj="
					+ id);
			final BufferedReader reader = new BufferedReader(
					new InputStreamReader(url.openStream()));

			String line;
			int i = 0;
			while ((line = reader.readLine()) != null) {
				if (line.equals("<div class=" + '"' + "subsectionHeader" + '"'
						+ ">")) {
					i++;
					continue;
				}
				if (i == 1) {
					return line;
				}
			}
		} catch (Exception e) {

		}
		return null;
	}

	public String[] IDtoName(int[] ids) {
		ArrayList<String> s = new ArrayList<String>();
		for (int r = 0; r < ids.length; r++) {
			try {
				URL url = new URL(
						"http://itemdb-rs.runescape.com/viewitem.ws?obj="
								+ ids[r]);
				final BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream()));

				String line;
				int i = 0;
				while ((line = reader.readLine()) != null) {
					if (line.equals("<div class=" + '"' + "subsectionHeader"
							+ '"' + ">")) {
						i++;
						continue;
					}
					if (i == 1) {
						s.add(line);
						break;
					}
				}
			} catch (Exception e) {

			}
		}
		return s.toArray(new String[s.size()]);
	}

}
